package com.core.indexer;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Set;


public class IndexerCore {

	private boolean mDebug;
	private boolean mPrint;
	
	public static final int DEBUG_DOC_COUNT = 20;
	public static final String TAG_DOC_START = "<DOC>";
	public static final String TAG_DOC_END = "</DOC>";
	public static final String TAG_DOC_NO_START = "<DOCNO>";
	public static final String TAG_DOC_NO_END = "</DOCNO>";
	public static final String TAG_DOC_HL_START = "<HEADLINE>";
	public static final String TAG_DOC_HL_END = "</HEADLINE>";
	public static final String TAG_DOC_TEXT_START = "<TEXT>";
	public static final String TAG_DOC_TEXT_END = "</TEXT>";
	
	public void DoIndex( String fileName, String stopListPath, boolean bPrint )
	{
		DoIndex(fileName, stopListPath, bPrint, false);
	}
	
	public void DoIndex( String fileName, String stopListPath, boolean bPrint, boolean bDebugMode )
	{
		mDebug = bDebugMode;
		mPrint = bPrint;
		Set<String> stopList; 
		IndexData.Get().Init(false); //Just init IndexData
		int nSeqNum = 0;
		
		try {
			FileManager.Get().InitForIndex();
			stopList = FileManager.Get().loadStoplist(stopListPath);
			
			//Parsing input XML documents. Fill docList with Document objects.
			if(mPrint)
				System.out.println("Parsing input file....");
			BufferedReader br = new BufferedReader(new FileReader(fileName));
			String line;
		     while((line = br.readLine()) != null) {
	             if(line.equalsIgnoreCase(TAG_DOC_START))
	             {
	            	 Document doc = GetDoc(br, nSeqNum);
	            	 if(doc != null)
	            	 {
	            		 if(mPrint)
	            			 System.out.println(String.format("Analyze [%s]...", doc.GetDocNo()));
	            		 doc.analyze(stopList);
	            		 FileManager.Get().saveMap(doc);
		            	 nSeqNum++;
	            	 }
	             }
	        }
			br.close();
			if(mPrint)
				System.out.println("Parsing input file [DONE]....");
			//Parsing input XML End
						
			if(mPrint)
			{
				System.out.println("Post processing and saving data files....Please Wait!");
			}
			// Calculate the file offset for each Inverted List
			IndexData.Get().ComputeInvertedListOffset();
			
			FileManager.Get().saveLexicon();
			FileManager.Get().saveInvlists();
			
			FileManager.Get().UnInitForIndex();
			if(mPrint)
			{
				System.out.println("Post processing and saving data files [DONE]....");
				System.out.println("[ALL DONE]");
			}
		} catch (IOException e) {
			System.out.println(String.format("File[%s] not found!...", fileName));
			e.printStackTrace();
		} finally {
			
		}
	}
	
	private Document GetDoc(BufferedReader br, int nSeqNum)
	{
		
		String strDocNo = "";
		String strDocHeadLine = "";
		String strDocContent = "";
		String line = "";
		try {
			while((line = br.readLine()) != null)
			{
				if(line.equalsIgnoreCase(TAG_DOC_END))
				{
					break;
				}
				else if(line.equalsIgnoreCase(TAG_DOC_HL_START))
				{
					strDocHeadLine = GetHeadLine(br);
				}
				else if(line.equalsIgnoreCase(TAG_DOC_TEXT_START))
				{
					strDocContent = GetText(br);
				}
				else
				{
					int nIdxStart = line.indexOf(TAG_DOC_NO_START);
					int nIdxEnd = line.indexOf(TAG_DOC_NO_END);
					if(nIdxStart >= 0 && nIdxEnd >= 0)
					{
						strDocNo = line.substring(nIdxStart+TAG_DOC_NO_START.length(), nIdxEnd).trim();
					}
				}
				
			}
			
			if(mPrint)
			{
				System.out.println(String.format("[%d]Parsing->Doc[%s]", nSeqNum, strDocNo));
				if(mDebug)
				{
					System.out.println(String.format("HeadLine: %s", strDocHeadLine));
				}
			}
			Document doc = new Document(nSeqNum, strDocNo, strDocHeadLine, strDocContent);
			return doc;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}

	}
	
	private String GetHeadLine(BufferedReader br)
	{
		String line;
		String ret = "";
		try {
			while((line = br.readLine()) != null)
			{
				if(line.equalsIgnoreCase(TAG_DOC_HL_END))
					return ret;
				
				ret += line;
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return ret;
		}
		
		return ret;
	}
	
	private String GetText(BufferedReader br)
	{
		String line;
		String ret = "";
		try {
			while((line = br.readLine()) != null)
			{
				if(line.equalsIgnoreCase(TAG_DOC_TEXT_END))
					return ret;
				
				ret += line;
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return ret;
		}
		
		return ret;
	}
}
